home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-05-21 | 3.0 KB | 83 lines | [TEXT/ttxt] |
- -- note that the version in the book is revised here
- -- one line is changed in the function dThreadFn
-
- -- create the control function for Dispatcher.dThread
- function dThreadFn dispatcher -> (
- repeat while true do (
- if dispatcher.action == undefined then (
- -- thread blocks here until the flag is acquired
- acquire dispatcher.dCond -- block, don’t poll!
- -- a condition activates any waiting threads and
- -- is immediately closed again.
- continue -- now execute the loop again
- ) else (
- -- work with a local copy and set action to undefined
- local actionCopy := dispatcher.action
- dispatcher.action := undefined
- if hasKey dispatcher.dispatchList actionCopy then
- -- note that this line is different from what is in the book
- (dispatcher.dispatchList[actionCopy]) dispatcher.args
- else
- format debug "undefined action" @normal
- )
- )
- )
-
- -- this class provides a framework for a thread that waits for calls
- -- the thread that it creates is at high priority
- -- most of the time, it is blocked, waiting to be called
- -- when it receives a function call that it knows how to respond to,
- -- it calls that function with the argument it is given
- -- presumably, that function might activate a lower priority thread
- -- so that the dispatcher can go back to listening for more calls
- -- while the lower priority thread responds
-
- class Dispatcher (RootObject)
- instance variables
- dispatchList -- SortedKeyedArray
- dThread -- a thread for responding to user actions
- dCond -- a condition that prevents us from trying to
- -- respond to a new action until the old one is dispatched
- action -- name of action we are currently responding to
- args -- list of arguments that goes with action
- instance methods
- method init self #rest args -> (
- self.dispatchList := new SortedKeyedArray
- -- note that the condition is defined before the thread
- -- the thread starts active, and immediately blocks while
- -- waiting to acquire the condition
- self.dCond := new Condition label:self
- self.dThread := new RegularThread \
- func:dThreadFn arg:self priority:@high
- self.action := undefined
- self.args := undefined
- apply nextMethod self args
- )
- method pleaseDo self act argument -> (
- if (hasKey self.dispatchList act) then (
- self.action := act
- self.args := argument
- relinquish self.dCond -- open the gate
- ) else (
- format debug "action not defined here" @normal
- )
- )
- end -- (Dispatcher class definition)
-
-
-
-
- global gDispatcher := new Dispatcher -- create an instance
- -- the init method on Dispatcher automatically creates a thread
- -- define the functions that will be called
- global fn func1 x -> format debug "Function 1 with %*\n" x @normal
- global fn func2 x -> format debug "Function 2 with %*\n" x @normal
- global fn func3 x -> format debug "Function 3 with %*\n" x @normal
- -- now add key-value pairs, addMany is a method on Collection
- addMany gDispatcher.dispatchList #(@act1:func1, @act2:func2, @act3:func3)
-
- -- now test the dispatcher
- pleaseDo gDispatcher @act1 ("Larry" as String)
- pleaseDo gDispatcher @act2 ("Curly" as String)
- pleaseDo gDispatcher @act3 ("Moe" as String)
-